﻿Imports System.IO

Public Class ImageFileTypes

    'http://stackoverflow.com/questions/9354747/how-can-i-determine-if-a-file-is-an-image-file-in-net

    Public Enum ImageTypes
        Unknown
        JPEG
        PNG
        GIF
        BMP
        TIFF
    End Enum

    Public Shared Function getFileType(ByVal fileName As String) As ImageTypes
        Dim headerBytes() As Byte

        If Not File.Exists(fileName) Then Return ImageTypes.Unknown

        Using fileStream As New FileStream(fileName, FileMode.Open)
            Const mostBytesNeeded As Integer = 11 'For JPEG
            If fileStream.Length < mostBytesNeeded Then Return ImageTypes.Unknown
            headerBytes = New Byte(mostBytesNeeded - 1) {}
            fileStream.Read(headerBytes, 0, mostBytesNeeded)
        End Using

        'Sources:
        'http://stackoverflow.com/questions/9354747
        'http://en.wikipedia.org/wiki/Magic_number_%28programming%29#Magic_numbers_in_files
        'http://www.mikekunz.com/image_file_header.html

        'JPEG:
        If headerBytes(0) = &HFF AndAlso headerBytes(1) = &HD8 AndAlso ((headerBytes(6) = &H4A AndAlso headerBytes(7) = &H46 AndAlso headerBytes(8) = &H49 AndAlso headerBytes(9) = &H46) OrElse (headerBytes(6) = &H45 AndAlso headerBytes(7) = &H78 AndAlso headerBytes(8) = &H69 AndAlso headerBytes(9) = &H66)) AndAlso headerBytes(10) = 0 Then ''EXIF' - 'JFIF' - FF D8
            Return ImageTypes.JPEG
        End If
        'PNG 
        If headerBytes(0) = &H89 AndAlso headerBytes(1) = &H50 AndAlso headerBytes(2) = &H4E AndAlso headerBytes(3) = &H47 AndAlso headerBytes(4) = &HD AndAlso headerBytes(5) = &HA AndAlso headerBytes(6) = &H1A AndAlso headerBytes(7) = &HA Then '89 50 4E 47 0D 0A 1A 0A
            Return ImageTypes.PNG
        End If
        'GIF
        If headerBytes(0) = &H47 AndAlso headerBytes(1) = &H49 AndAlso headerBytes(2) = &H46 Then ''GIF'
            Return ImageTypes.GIF
        End If
        'BMP
        If headerBytes(0) = &H42 AndAlso headerBytes(1) = &H4D Then '42 4D
            Return ImageTypes.BMP
        End If
        'TIFF
        If (headerBytes(0) = &H49 AndAlso headerBytes(1) = &H49 AndAlso headerBytes(2) = &H2A AndAlso headerBytes(3) = &H0) OrElse (headerBytes(0) = &H4D AndAlso headerBytes(1) = &H4D AndAlso headerBytes(2) = &H0 AndAlso headerBytes(3) = &H2A) Then '4D 4D 00 2A - 49 49 2A 00
            Return ImageTypes.TIFF
        End If

        Return ImageTypes.Unknown
    End Function

End Class
